package com.ruyuan.seckilling.inventory.controller;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.ruyuan.seckilling.common.MapResult;
import com.ruyuan.seckilling.inventory.service.InventoryService;
import com.ruyuan.seckilling.inventory.vo.ProductStockVo;
import com.ruyuan.seckilling.inventory.vo.QueryCurrentStockRequest;
import com.ruyuan.seckilling.inventory.vo.SalePercent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.NumberFormat;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author zhonghuashishan
 */
@Slf4j
@RestController
@RequestMapping("/inventory/frontend")
public class FrontendInventoryController {

    @Autowired
    private InventoryService inventoryService;

    private final LoadingCache<String, List<SalePercent>> salePercentCache = CacheBuilder.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(15, TimeUnit.SECONDS)
            .refreshAfterWrite(10, TimeUnit.SECONDS)
            .build(new CacheLoader<String, List<SalePercent>>() {
                @Override
                public List<SalePercent> load(String key) throws Exception {
                    return loadSalePercent(key);
                }
            });

    @PostMapping("/queryCurrentStock")
    public MapResult queryCurrentStock(@RequestBody QueryCurrentStockRequest request) {
        String validateResult = request.validateParams();
        if (Objects.nonNull(validateResult)) {
            return MapResult.errorResult().setInfo(validateResult);
        }

        // key的格式为activityId:skuId,skuId
        String key = request.getActivityId() + ":" + request.getSkuIds().stream()
                .map(e -> e +"").collect(Collectors.joining(","));
        List<SalePercent> dataList = Collections.emptyList();
        try {
            dataList = salePercentCache.get(key);
        } catch (ExecutionException e) {
            dataList = loadSalePercent(key);
        }
        return MapResult.successResult().setDataList(dataList);
    }

    private List<SalePercent> loadSalePercent(String key) {
        String activityId = key.substring(0, key.indexOf(":"));
        String[] skuIds = key.substring(key.indexOf(":") + 1).split(",");
        List<SalePercent> list = new ArrayList<>();
        for (String skuId : skuIds) {
            ProductStockVo productStockVo = inventoryService.queryCurrentStock(Long.parseLong(activityId), Long.parseLong(skuId));
            list.add(calculateSalePercent(productStockVo));
        }
        return list;
    }

    private SalePercent calculateSalePercent(ProductStockVo productStockVo) {
        Integer salableStock = productStockVo.getSalableStock();
        Integer lockedStock = productStockVo.getLockedStock();
        Integer saledStock = productStockVo.getSaledStock();

        // 三者相加等于这个商品的总库存
        int totalStock = salableStock + lockedStock + saledStock;
        double percent = (double) (totalStock - salableStock) / totalStock;
        NumberFormat percentInstance = NumberFormat.getPercentInstance();
        String format = percentInstance.format(percent);
        return new SalePercent(productStockVo.getSkuId(), format);
    }
}
